<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.16">
<title>Boost.ContainerHash</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;-webkit-tap-highlight-color:transparent}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<style>
pre.rouge table td { padding: 5px; }
pre.rouge table pre { margin: 0; }
pre.rouge .cm {
  color: #999988;
  font-style: italic;
}
pre.rouge .cp {
  color: #999999;
  font-weight: bold;
}
pre.rouge .c1 {
  color: #999988;
  font-style: italic;
}
pre.rouge .cs {
  color: #999999;
  font-weight: bold;
  font-style: italic;
}
pre.rouge .c, pre.rouge .ch, pre.rouge .cd, pre.rouge .cpf {
  color: #999988;
  font-style: italic;
}
pre.rouge .err {
  color: #a61717;
  background-color: #e3d2d2;
}
pre.rouge .gd {
  color: #000000;
  background-color: #ffdddd;
}
pre.rouge .ge {
  color: #000000;
  font-style: italic;
}
pre.rouge .gr {
  color: #aa0000;
}
pre.rouge .gh {
  color: #999999;
}
pre.rouge .gi {
  color: #000000;
  background-color: #ddffdd;
}
pre.rouge .go {
  color: #888888;
}
pre.rouge .gp {
  color: #555555;
}
pre.rouge .gs {
  font-weight: bold;
}
pre.rouge .gu {
  color: #aaaaaa;
}
pre.rouge .gt {
  color: #aa0000;
}
pre.rouge .kc {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kd {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kn {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kp {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kr {
  color: #000000;
  font-weight: bold;
}
pre.rouge .kt {
  color: #445588;
  font-weight: bold;
}
pre.rouge .k, pre.rouge .kv {
  color: #000000;
  font-weight: bold;
}
pre.rouge .mf {
  color: #009999;
}
pre.rouge .mh {
  color: #009999;
}
pre.rouge .il {
  color: #009999;
}
pre.rouge .mi {
  color: #009999;
}
pre.rouge .mo {
  color: #009999;
}
pre.rouge .m, pre.rouge .mb, pre.rouge .mx {
  color: #009999;
}
pre.rouge .sa {
  color: #000000;
  font-weight: bold;
}
pre.rouge .sb {
  color: #d14;
}
pre.rouge .sc {
  color: #d14;
}
pre.rouge .sd {
  color: #d14;
}
pre.rouge .s2 {
  color: #d14;
}
pre.rouge .se {
  color: #d14;
}
pre.rouge .sh {
  color: #d14;
}
pre.rouge .si {
  color: #d14;
}
pre.rouge .sx {
  color: #d14;
}
pre.rouge .sr {
  color: #009926;
}
pre.rouge .s1 {
  color: #d14;
}
pre.rouge .ss {
  color: #990073;
}
pre.rouge .s, pre.rouge .dl {
  color: #d14;
}
pre.rouge .na {
  color: #008080;
}
pre.rouge .bp {
  color: #999999;
}
pre.rouge .nb {
  color: #0086B3;
}
pre.rouge .nc {
  color: #445588;
  font-weight: bold;
}
pre.rouge .no {
  color: #008080;
}
pre.rouge .nd {
  color: #3c5d5d;
  font-weight: bold;
}
pre.rouge .ni {
  color: #800080;
}
pre.rouge .ne {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nf, pre.rouge .fm {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nl {
  color: #990000;
  font-weight: bold;
}
pre.rouge .nn {
  color: #555555;
}
pre.rouge .nt {
  color: #000080;
}
pre.rouge .vc {
  color: #008080;
}
pre.rouge .vg {
  color: #008080;
}
pre.rouge .vi {
  color: #008080;
}
pre.rouge .nv, pre.rouge .vm {
  color: #008080;
}
pre.rouge .ow {
  color: #000000;
  font-weight: bold;
}
pre.rouge .o {
  color: #000000;
  font-weight: bold;
}
pre.rouge .w {
  color: #bbbbbb;
}
pre.rouge {
  background-color: #f8f8f8;
}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Boost.ContainerHash</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#intro">Introduction</a></li>
<li><a href="#tutorial">Tutorial</a></li>
<li><a href="#custom">Extending boost::hash for a custom data type</a></li>
<li><a href="#combine">Combining hash values</a></li>
<li><a href="#portability">Portability</a></li>
<li><a href="#disable">Disabling The Extensions</a></li>
<li><a href="#changes">Change Log</a>
<ul class="sectlevel2">
<li><a href="#changes_boost_1_67_0">Boost 1.67.0</a></li>
<li><a href="#changes_boost_1_66_0">Boost 1.66.0</a></li>
<li><a href="#changes_boost_1_65_0">Boost 1.65.0</a></li>
<li><a href="#changes_boost_1_64_0">Boost 1.64.0</a></li>
<li><a href="#changes_boost_1_63_0">Boost 1.63.0</a></li>
<li><a href="#changes_boost_1_58_0">Boost 1.58.0</a></li>
<li><a href="#changes_boost_1_56_0">Boost 1.56.0</a></li>
<li><a href="#changes_boost_1_55_0">Boost 1.55.0</a></li>
<li><a href="#changes_boost_1_54_0">Boost 1.54.0</a></li>
<li><a href="#changes_boost_1_53_0">Boost 1.53.0</a></li>
<li><a href="#changes_boost_1_52_0">Boost 1.52.0</a></li>
<li><a href="#changes_boost_1_51_0">Boost 1.51.0</a></li>
<li><a href="#changes_boost_1_50_0">Boost 1.50.0</a></li>
<li><a href="#changes_boost_1_46_0">Boost 1.46.0</a></li>
<li><a href="#changes_boost_1_44_0">Boost 1.44.0</a></li>
<li><a href="#changes_boost_1_43_0">Boost 1.43.0</a></li>
<li><a href="#changes_boost_1_42_0">Boost 1.42.0</a></li>
<li><a href="#changes_boost_1_40_0">Boost 1.40.0</a></li>
<li><a href="#changes_boost_1_39_0">Boost 1.39.0</a></li>
<li><a href="#changes_boost_1_38_0">Boost 1.38.0</a></li>
<li><a href="#changes_boost_1_37_0">Boost 1.37.0</a></li>
<li><a href="#changes_boost_1_36_0">Boost 1.36.0</a></li>
<li><a href="#changes_boost_1_35_0">Boost 1.35.0</a></li>
<li><a href="#changes_boost_1_34_1">Boost 1.34.1</a></li>
<li><a href="#changes_boost_1_34_0">Boost 1.34.0</a></li>
<li><a href="#changes_boost_1_33_1">Boost 1.33.1</a></li>
<li><a href="#changes_boost_1_33_0">Boost 1.33.0</a></li>
</ul>
</li>
<li><a href="#rationale">Rationale</a>
<ul class="sectlevel2">
<li><a href="#rationale_quality_of_the_hash_function">Quality of the hash function</a></li>
</ul>
</li>
<li><a href="#ref">Reference</a>
<ul class="sectlevel2">
<li><a href="#ref_header_boostcontainer_hashhash_hpp">Header &lt;boost/container_hash/hash.hpp&gt;</a></li>
<li><a href="#ref_struct_template_hash">Struct template hash</a></li>
<li><a href="#ref_specializations">Specializations</a></li>
<li><a href="#ref_support_functions_boost_extension">Support functions (Boost extension).</a></li>
<li><a href="#ref_overloadable_hash_implementation_boost_extension">Overloadable hash implementation (Boost extension).</a></li>
</ul>
</li>
<li><a href="#links">Links</a></li>
<li><a href="#thanks">Acknowledgements</a></li>
<li><a href="#copyright">Copyright and License</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="intro"><a class="link" href="#intro">Introduction</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>boost::hash</code> is an implementation of the <a href="https://en.wikipedia.org/wiki/Hash_function">hash function</a> object specified by the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">Draft Technical Report on C++ Library Extensions</a> (TR1). It is the default hash function for <a href="../../../unordered/index.html">Boost.Unordered</a>, <a href="../../../intrusive/index.html">Boost.Intrusive</a>'s unordered associative containers, and <a href="../../../multi_index/index.html">Boost.MultiIndex</a>'s hash indicies and <a href="../../../bimap/index.html">Boost.Bimap</a>'s <code>unordered_set_of</code>.</p>
</div>
<div class="paragraph">
<p>As it is compliant with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</a>, it will work with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>integers</p>
</li>
<li>
<p>floats</p>
</li>
<li>
<p>pointers</p>
</li>
<li>
<p>strings</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It also implements the extension proposed by Peter Dimov in issue 6.18 of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</a> (page 63), this adds support for:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>arrays</p>
</li>
<li>
<p><code>std::pair</code></p>
</li>
<li>
<p>the standard containers.</p>
</li>
<li>
<p>extending <code>boost::hash</code> for custom types.</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
This hash function is designed to be used in containers based on the STL and is not suitable as a general purpose hash function. For more details see the <a href="#rationale">rationale</a>.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="tutorial"><a class="link" href="#tutorial">Tutorial</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>When using a hash index with <a href="../../../multi_index/index.html">Boost.MultiIndex</a>, you don&#8217;t need to do anything to use <code>boost::hash</code> as it uses it by default. To find out how to use a user-defined type, read the <a href="#custom">section on extending boost::hash for a custom data type</a>.</p>
</div>
<div class="paragraph">
<p>If your standard library supplies its own implementation of the unordered associative containers and you wish to use <code>boost::hash</code>, just use an extra template parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="n">unordered_multiset</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&gt;</span>
        <span class="n">set_of_ints</span><span class="p">;</span>

<span class="n">std</span><span class="o">::</span><span class="n">unordered_set</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="o">&gt;</span>
        <span class="n">set_of_pairs</span><span class="p">;</span>

<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">map_int_to_string</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>To use <code>boost::hash</code> directly, create an instance and call it as a function:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include &lt;boost/container_hash/hash.hpp&gt;
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">string_hash</span><span class="p">;</span>

    <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">h</span> <span class="o">=</span> <span class="n">string_hash</span><span class="p">(</span><span class="s">"Hash me"</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>For an example of generic use, here is a function to generate a vector containing the hashes of the elements of a container:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Container</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">get_hashes</span><span class="p">(</span><span class="n">Container</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">hashes</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">transform</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">x</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">hashes</span><span class="p">),</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">Container</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">());</span>

    <span class="k">return</span> <span class="n">hashes</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="custom"><a class="link" href="#custom">Extending boost::hash for a custom data type</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>boost::hash</code> is implemented by calling the function <code>hash_value</code>. The namespace isn&#8217;t specified so that it can detect overloads via argument dependant lookup. So if there is a free function <code>hash_value</code> in the same namespace as a custom type, it will get called.</p>
</div>
<div class="paragraph">
<p>If you have a structure <code>library::book</code>, where each book is uniquely defined by its member <code>id</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">library</span>
<span class="p">{</span>
    <span class="k">struct</span> <span class="nc">book</span>
    <span class="p">{</span>
        <span class="kt">int</span> <span class="n">id</span><span class="p">;</span>
        <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">author</span><span class="p">;</span>
        <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">title</span><span class="p">;</span>

        <span class="c1">// ....</span>
    <span class="p">};</span>

    <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">book</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">book</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">a</span><span class="p">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Then all you would need to do is write the function <code>library::hash_value</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">library</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">book</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">hasher</span><span class="p">;</span>
        <span class="k">return</span> <span class="n">hasher</span><span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">id</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>And you can now use <code>boost::hash</code> with book:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">library</span><span class="o">::</span><span class="n">book</span> <span class="nf">knife</span><span class="p">(</span><span class="mi">3458</span><span class="p">,</span> <span class="s">"Zane Grey"</span><span class="p">,</span> <span class="s">"The Hash Knife Outfit"</span><span class="p">);</span>
<span class="n">library</span><span class="o">::</span><span class="n">book</span> <span class="nf">dandelion</span><span class="p">(</span><span class="mi">1354</span><span class="p">,</span> <span class="s">"Paul J. Shanley"</span><span class="p">,</span>
    <span class="s">"Hash &amp; Dandelion Greens"</span><span class="p">);</span>

<span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="n">library</span><span class="o">::</span><span class="n">book</span><span class="o">&gt;</span> <span class="n">book_hasher</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">knife_hash_value</span> <span class="o">=</span> <span class="n">book_hasher</span><span class="p">(</span><span class="n">knife</span><span class="p">);</span>

<span class="c1">// If std::unordered_set is available:</span>
<span class="n">std</span><span class="o">::</span><span class="n">unordered_set</span><span class="o">&lt;</span><span class="n">library</span><span class="o">::</span><span class="n">book</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="n">library</span><span class="o">::</span><span class="n">book</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">books</span><span class="p">;</span>
<span class="n">books</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">knife</span><span class="p">);</span>
<span class="n">books</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">library</span><span class="o">::</span><span class="n">book</span><span class="p">(</span><span class="mi">2443</span><span class="p">,</span> <span class="s">"Lindgren, Torgny"</span><span class="p">,</span> <span class="s">"Hash"</span><span class="p">));</span>
<span class="n">books</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">library</span><span class="o">::</span><span class="n">book</span><span class="p">(</span><span class="mi">1953</span><span class="p">,</span> <span class="s">"Snyder, Bernadette M."</span><span class="p">,</span>
    <span class="s">"Heavenly Hash: A Tasty Mix of a Mother's Meditations"</span><span class="p">));</span>

<span class="n">assert</span><span class="p">(</span><span class="n">books</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">knife</span><span class="p">)</span> <span class="o">!=</span> <span class="n">books</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
<span class="n">assert</span><span class="p">(</span><span class="n">books</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">dandelion</span><span class="p">)</span> <span class="o">==</span> <span class="n">books</span><span class="p">.</span><span class="n">end</span><span class="p">());</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The full example can be found in: <a href="../../examples/books.hpp">/libs/container_hash/examples/books.hpp</a> and <a href="../../examples/books.cpp">/libs/container_hash/examples/books.cpp</a>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">
When writing a hash function, first look at how the equality function works. Objects that are equal must generate the same hash value. When objects are not equal they should generate different hash values. In this object equality was based just on the id so the hash function only hashes the id. If it was based on the object&#8217;s name and author then the hash function should take them into account (how to do this is discussed in the next section).
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="combine"><a class="link" href="#combine">Combining hash values</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Say you have a point class, representing a two dimensional location:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">point</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">x</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">y</span><span class="p">;</span>
<span class="nl">public:</span>
    <span class="n">point</span><span class="p">()</span> <span class="o">:</span> <span class="n">x</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">y</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{}</span>
    <span class="n">point</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="o">:</span> <span class="n">x</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">y</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">point</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="k">const</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">x</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="n">x</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and you wish to use it as the key for an unordered_map. You need to customise the hash for this structure. To do this we need to combine the hash values for x and y. The function <code>boost::hash_combine</code> is supplied for this purpose:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">point</span>
<span class="p">{</span>
    <span class="p">...</span>

    <span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">point</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">p</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
        <span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>

        <span class="k">return</span> <span class="n">seed</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="p">...</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Calls to <code>hash_combine</code> incrementally build the hash from the different members of <code>point</code>, it can be repeatedly called for any number of elements. It calls <code>hash_value</code> on the supplied element, and combines it with the seed.</p>
</div>
<div class="paragraph">
<p>Full code for this example is at <a href="../../examples/point.cpp">/libs/container_hash/examples/point.cpp</a>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
<div class="paragraph">
<p>When using <code>boost::hash_combine</code> the order of the calls matters.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>results in a different seed to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are calculating a hash value for data where the order of the data doesn&#8217;t matter in comparisons (e.g. a set) you will have to ensure that the data is always supplied in the same order.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To calculate the hash of an iterator range you can use <code>boost::hash_range</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">some_strings</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash_range</span><span class="p">(</span><span class="n">some_strings</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">some_strings</span><span class="p">.</span><span class="n">end</span><span class="p">());</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that when writing template classes, you might not want to include the main hash header as it&#8217;s quite an expensive include that brings in a lot of other headers, so instead you can include the <code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code> header which forward declares <code>boost::hash</code>, <code>boost::hash_range</code> and <code>boost::hash_combine</code>. You&#8217;ll need to include the main header before instantiating <code>boost::hash</code>. When using a container that uses <code>boost::hash</code> it should do that for you, so your type will work fine with the boost hash containers. There&#8217;s an example of this in <a href="../../examples/template.hpp">template.hpp</a> and <a href="../../examples/template.cpp">template.cpp</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="portability"><a class="link" href="#portability">Portability</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>boost::hash</code> is written to be as portable as possible, but unfortunately, several older compilers don&#8217;t support argument dependent lookup (ADL) - the mechanism used for customisation. On those compilers custom overloads for <code>hash_value</code> needs to be declared in the <code>boost</code> namespace.</p>
</div>
<div class="paragraph">
<p>On a strictly standards compliant compiler, an overload defined in the <code>boost</code> namespace won&#8217;t be found when <code>boost::hash</code> is instantiated, so for these compilers the overload should only be declared in the same namespace as the class.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s say we have a simple custom type:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">foo</span>
<span class="p">{</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
    <span class="k">class</span> <span class="nc">custom_type</span>
    <span class="p">{</span>
        <span class="n">T</span> <span class="n">value</span><span class="p">;</span>
    <span class="nl">public:</span>
        <span class="n">custom_type</span><span class="p">(</span><span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="o">:</span> <span class="n">value</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">{}</span>

        <span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">custom_type</span> <span class="n">x</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">hasher</span><span class="p">;</span>
            <span class="k">return</span> <span class="n">hasher</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">value</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">};</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>On a compliant compiler, when <code>hash_value</code> is called for this type, it will look at the namespace inside the type and find <code>hash_value</code> but on a compiler which doesn&#8217;t support ADL <code>hash_value</code> won&#8217;t be found. To make things worse, some compilers which do support ADL won&#8217;t find a friend class defined inside the class.</p>
</div>
<div class="paragraph">
<p>So first move the member function out of the class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">foo</span>
<span class="p">{</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
    <span class="k">class</span> <span class="nc">custom_type</span>
    <span class="p">{</span>
        <span class="n">T</span> <span class="n">value</span><span class="p">;</span>
    <span class="nl">public:</span>
        <span class="n">custom_type</span><span class="p">(</span><span class="n">T</span> <span class="n">x</span><span class="p">)</span> <span class="o">:</span> <span class="n">value</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">{}</span>

        <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash</span><span class="p">(</span><span class="n">custom_type</span> <span class="n">x</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">boost</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">hasher</span><span class="p">;</span>
            <span class="k">return</span> <span class="n">hasher</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">};</span>

    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
    <span class="kr">inline</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">custom_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">x</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">x</span><span class="p">.</span><span class="n">hash</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Unfortunately, I couldn&#8217;t declare <code>hash_value</code> as a friend, as some compilers don&#8217;t support template friends, so instead I declared a member function to calculate the hash, and called it from <code>hash_value</code>.</p>
</div>
<div class="paragraph">
<p>For compilers which don&#8217;t support ADL, <code>hash_value</code> needs to be defined in the <code>boost</code> namespace:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
</span><span class="k">namespace</span> <span class="n">boost</span>
<span class="cp">#else
</span><span class="k">namespace</span> <span class="n">foo</span>
<span class="cp">#endif
</span><span class="p">{</span>
    <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
    <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">foo</span><span class="o">::</span><span class="n">custom_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">x</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">x</span><span class="p">.</span><span class="n">hash</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Full code for this example is at <a href="../../examples/portable.cpp">/libs/container_hash/examples/portable.cpp</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="disable"><a class="link" href="#disable">Disabling The Extensions</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>While <code>boost::hash</code>'s extensions are generally useful, you might want to turn them of in order to check that your code will work with other implementations of TR1. To do this define the macro <code>BOOST_HASH_NO_EXTENSIONS</code>. When this macro is defined, only the specialisations detailed in TR1 will be declared. But, if you later undefine the macro and include <code>&lt;boost/container_hash/hash.hpp&gt;</code> then the non-specialised form will be defined - activating the extensions.</p>
</div>
<div class="paragraph">
<p>It is strongly recommended that you never undefine the macro - and only define it so that it applies to the complete translation unit, either by defining it at the beginning of the main source file or, preferably, by using a compiler switch or preference. And you really should never define it in header files.</p>
</div>
<div class="paragraph">
<p>If you are writing a library which has code in the header which requires the extensions, then the best action is to tell users not to define the macro. Their code won&#8217;t <em>require</em> the macro.</p>
</div>
<div class="paragraph">
<p>Translation units that are compiled with the macro defined will link with units that were compiled without it. This feature has been designed to avoid ODR violations.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="changes"><a class="link" href="#changes">Change Log</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="changes_boost_1_67_0"><a class="link" href="#changes_boost_1_67_0">Boost 1.67.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Moved library into its own module, <code>container_hash</code>.</p>
</li>
<li>
<p>Moved headers for new module name, now at: <code>&lt;boost/container_hash/hash.hpp&gt;</code>, <code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>, <code>&lt;boost/container_hash/extensions.hpp&gt;</code>.</p>
</li>
<li>
<p>Added forwarding headers to support the old headers locations.</p>
</li>
<li>
<p>Support <code>std::string_view</code>, <code>std::error_code</code>, <code>std::error_condition</code>, <code>std::optional</code>, <code>std::variant</code>, <code>std::monostate</code> where available.</p>
</li>
<li>
<p>Update include paths from other Boost libraries.</p>
</li>
<li>
<p>Manually write out tuple overloads, rather than using the preprocessor to generate them. Should improve usability, due to better error messages, and easier debugging.</p>
</li>
<li>
<p>Fix tutorial example (<a href="https://svn.boost.org/trac/boost/ticket/11017">#11017</a>).</p>
</li>
<li>
<p>Quick fix for hashing <code>vector&lt;bool&gt;</code> when using libC++. Will try to introduce a more general fix in the next release.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_66_0"><a class="link" href="#changes_boost_1_66_0">Boost 1.66.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Avoid float comparison warning when using Clang - this workaround was already in place for GCC, and was used when Clang pretends to be GCC, but the warning was appearing when running Clang in other contexts.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_65_0"><a class="link" href="#changes_boost_1_65_0">Boost 1.65.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Support for <code>char16_t</code>, <code>char32_t</code>, <code>u16string</code>, <code>u32string</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_64_0"><a class="link" href="#changes_boost_1_64_0">Boost 1.64.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Fix for recent versions of Visual C++ which have removed <code>std::unary_function</code> and <code>std::binary_function</code> (<a href="https://svn.boost.org/trac/boost/ticket/12353">#12353</a>).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_63_0"><a class="link" href="#changes_boost_1_63_0">Boost 1.63.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Fixed some warnings.</p>
</li>
<li>
<p>Only define hash for <code>std::wstring</code> when we know we have a <code>wchar_t</code>. Otherwise there&#8217;s a compile error as there&#8217;s no overload for hashing the characters in wide strings (<a href="https://svn.boost.org/trac/boost/ticket/8552">#8552</a>).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_58_0"><a class="link" href="#changes_boost_1_58_0">Boost 1.58.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Fixed strict aliasing violation (<a href="https://github.com/boostorg/container_hash/issues/3">GitHub #3</a>).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_56_0"><a class="link" href="#changes_boost_1_56_0">Boost 1.56.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Removed some Visual C++ 6 workarounds.</p>
</li>
<li>
<p>Ongoing work on improving <code>hash_combine</code>. This changes the combine function which was previously defined in the reference documentation.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_55_0"><a class="link" href="#changes_boost_1_55_0">Boost 1.55.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Simplify a SFINAE check so that it will hopefully work on Sun 5.9 (<a href="https://svn.boost.org/trac10/ticket/8822">#8822</a>).</p>
</li>
<li>
<p>Suppress Visual C++ infinite loop warning (<a href="https://svn.boost.org/trac10/ticket/8568">#8568</a>).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_54_0"><a class="link" href="#changes_boost_1_54_0">Boost 1.54.0</a></h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/7957">Ticket 7957</a>: Fixed a typo.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_53_0"><a class="link" href="#changes_boost_1_53_0">Boost 1.53.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Add support for <code>boost::int128_type</code> and <code>boost::uint128_type</code> where available - currently only <code>__int128</code> and <code>unsigned __int128</code> on some versions of gcc.</p>
</li>
<li>
<p>On platforms that are known to have the standard floating point functions, don&#8217;t use automatic detection - which can break if there are ambiguous overloads.</p>
</li>
<li>
<p>Fix undefined behaviour when using the binary <code>float</code> hash (Thomas Heller).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_52_0"><a class="link" href="#changes_boost_1_52_0">Boost 1.52.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Restore <code>enum</code> support, which was accidentally removed in the last version.</p>
</li>
<li>
<p>New floating point hasher - will hash the binary representation on more platforms, which should be faster.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_51_0"><a class="link" href="#changes_boost_1_51_0">Boost 1.51.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Support the standard smart pointers.</p>
</li>
<li>
<p><code>hash_value</code> now implemented using SFINAE to avoid implicit casts to built in types when calling it.</p>
</li>
<li>
<p>Updated to use the new config macros.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_50_0"><a class="link" href="#changes_boost_1_50_0">Boost 1.50.0</a></h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/6771">Ticket 6771</a>: Avoid gcc&#8217;s <code>-Wfloat-equal</code> warning.</p>
</li>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/6806">Ticket 6806</a>: Support <code>std::array</code> and <code>std::tuple</code> when available.</p>
</li>
<li>
<p>Add deprecation warning to the long deprecated <code>boost/container_hash/detail/container_fwd.hpp</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_46_0"><a class="link" href="#changes_boost_1_46_0">Boost 1.46.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Avoid warning due with gcc&#8217;s <code>-Wconversion</code> flag.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_44_0"><a class="link" href="#changes_boost_1_44_0">Boost 1.44.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Add option to prevent implicit conversions when calling <code>hash_value</code> by defining <code>BOOST_HASH_NO_IMPLICIT_CASTS</code>. When using <code>boost::hash</code> for a type that does not have <code>hash_value</code> declared but does have an implicit conversion to a type that does, it would use that implicit conversion to hash it. Which can sometimes go very wrong, e.g. using a conversion to <code>bool</code> and only hashing to 2 possible values. Since fixing this is a breaking change and was only approached quite late in the release cycle with little discussion it&#8217;s opt-in for now. This, or something like it, will become the default in a future version.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_43_0"><a class="link" href="#changes_boost_1_43_0">Boost 1.43.0</a></h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/3866">Ticket 3866</a>: Don&#8217;t foward declare containers when using gcc&#8217;s parallel library, allow user to stop forward declaration by defining the <code>BOOST_DETAIL_NO_CONTAINER_FWD</code> macro.</p>
</li>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/4038">Ticket 4038</a>: Avoid hashing <code>0.5</code> and <code>0</code> to the same number.</p>
</li>
<li>
<p>Stop using deprecated <code>BOOST_HAS_*</code> macros.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_42_0"><a class="link" href="#changes_boost_1_42_0">Boost 1.42.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Reduce the number of warnings for Visual C++ warning level 4.</p>
</li>
<li>
<p>Some code formatting changes to fit lines into 80 characters.</p>
</li>
<li>
<p>Rename an internal namespace.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_40_0"><a class="link" href="#changes_boost_1_40_0">Boost 1.40.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Automatically configure the <code>float</code> functions using template metaprogramming instead of trying to configure every possibility manually.</p>
</li>
<li>
<p>Workaround for when STLport doesn&#8217;t support long double.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_39_0"><a class="link" href="#changes_boost_1_39_0">Boost 1.39.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Move the <code>hash_fwd.hpp</code> implementation into the hash subdirectory, leaving a forwarding header in the old location. You should still use the old location, the new location is mainly for implementation and possible modularization.</p>
</li>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/2412">Ticket 2412</a>: Removed deprecated headers.</p>
</li>
<li>
<p><a href="https://svn.boost.org/trac/boost/ticket/2957">Ticket 2957</a>: Fix configuration for vxworks.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_38_0"><a class="link" href="#changes_boost_1_38_0">Boost 1.38.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Changed the warnings in the deprecated headers from 1.34.0 to errors. These will be removed in a future version of Boost.</p>
</li>
<li>
<p>Moved detail headers out of <code>boost/container_hash/detail</code>, since they are part of <code>functional/hash</code>, not <code>container_hash</code>. <code>boost/container_hash/detail/container_fwd.hpp</code> has been moved to <code>boost/detail/container_fwd.hpp</code> as it&#8217;s used outside of this library, the others have been moved to <code>boost/functional/hash/detail</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_37_0"><a class="link" href="#changes_boost_1_37_0">Boost 1.37.0</a></h3>
<div class="ulist">
<ul>
<li>
<p><a href="http://svn.boost.org/trac/boost/ticket/2264">Ticket 2264</a>: In Visual C++, always use C99 float functions for long double and float as the C++ overloads aren&#8217;t always availables.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_36_0"><a class="link" href="#changes_boost_1_36_0">Boost 1.36.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Stop using OpenBSD&#8217;s dodgy <code>std::numeric_limits</code>.</p>
</li>
<li>
<p>Using the boost typedefs for <code>long long</code> and <code>unsigned long long</code>.</p>
</li>
<li>
<p>Move the extensions into their own header.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_35_0"><a class="link" href="#changes_boost_1_35_0">Boost 1.35.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Support for <code>long long</code>, <code>std::complex</code>.</p>
</li>
<li>
<p>Improved algorithm for hashing floating point numbers:</p>
<div class="ulist">
<ul>
<li>
<p>Improved portablity, as described by Daniel Krügler in <a href="http://lists.boost.org/boost-users/2005/08/13418.php">a post to the boost users list</a>.</p>
</li>
<li>
<p>Fits more information into each combine loop, which can reduce the the number of times combine is called and hopefully give a better quality hash function.</p>
</li>
<li>
<p>Improved the algorithm for hashing floating point numbers.</p>
</li>
<li>
<p>On Cygwin use a binary hash function for floating point numbers, as Cygwin doesn&#8217;t have decent floating point functions for <code>long double</code>.</p>
</li>
<li>
<p>Never uses <code>fpclass</code> which doesn&#8217;t support <code>long double</code>.</p>
</li>
<li>
<p><a href="http://svn.boost.org/trac/boost/ticket/1064">Ticket 1064</a>: Removed unnecessary use of errno.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Explicitly overload for more built in types.</p>
</li>
<li>
<p>Minor improvements to the documentation.</p>
</li>
<li>
<p>A few bug and warning fixes:</p>
<div class="ulist">
<ul>
<li>
<p><a href="http://svn.boost.org/trac/boost/ticket/1509">Ticket 1509</a>: Suppress another Visual C++ warning.</p>
</li>
<li>
<p>Some workarounds for the Sun compilers.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_34_1"><a class="link" href="#changes_boost_1_34_1">Boost 1.34.1</a></h3>
<div class="ulist">
<ul>
<li>
<p><a href="https://svn.boost.org/trac10/ticket/952">Ticket 952</a>: Suppress incorrect 64-bit warning on Visual C++.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_34_0"><a class="link" href="#changes_boost_1_34_0">Boost 1.34.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Use declarations for standard classes, so that the library doesn&#8217;t need to include all of their headers</p>
</li>
<li>
<p>Deprecated the <code>&lt;boost/functional/hash/*.hpp&gt;</code> headers. Now a single header, <code>&lt;boost/functional/hash.hpp&gt;</code> is used.</p>
</li>
<li>
<p>Add support for the <code>BOOST_HASH_NO_EXTENSIONS</code> macro, which disables the extensions to TR1.</p>
</li>
<li>
<p>Minor improvements to the hash functions for floating point numbers.</p>
</li>
<li>
<p>Update the portable example to hopefully be more generally portable.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_33_1"><a class="link" href="#changes_boost_1_33_1">Boost 1.33.1</a></h3>
<div class="ulist">
<ul>
<li>
<p>Fixed the points example, as pointed out by 沈慧峰.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="changes_boost_1_33_0"><a class="link" href="#changes_boost_1_33_0">Boost 1.33.0</a></h3>
<div class="ulist">
<ul>
<li>
<p>Initial Release</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="rationale"><a class="link" href="#rationale">Rationale</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The rationale can be found in the original design<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.</p>
</div>
<div class="sect2">
<h3 id="rationale_quality_of_the_hash_function"><a class="link" href="#rationale_quality_of_the_hash_function">Quality of the hash function</a></h3>
<div class="paragraph">
<p>Many hash functions strive to have little correlation between the input and output values. They attempt to uniformally distribute the output values for very similar inputs. This hash function makes no such attempt. In fact, for integers, the result of the hash function is often just the input value. So similar but different input values will often result in similar but different output values. This means that it is not appropriate as a general hash function. For example, a hash table may discard bits from the hash function resulting in likely collisions, or might have poor collision resolution when hash values are clustered together. In such cases this hash function will preform poorly.</p>
</div>
<div class="paragraph">
<p>But the standard has no such requirement for the hash function, it just requires that the hashes of two different values are unlikely to collide. Containers or algorithms designed to work with the standard hash function will have to be implemented to work well when the hash function&#8217;s output is correlated to its input. Since they are paying that cost a higher quality hash function would be wasteful.</p>
</div>
<div class="paragraph">
<p>For other use cases, if you do need a higher quality hash function, then neither the standard hash function or <code>boost::hash</code> are appropriate. There are several options available. One is to use a second hash on the output of this hash function, such as <a href="http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm">Thomas Wang&#8217;s hash function</a>. This this may not work as well as a hash algorithm tailored for the input.</p>
</div>
<div class="paragraph">
<p>For strings there are several fast, high quality hash functions available (for example <a href="http://code.google.com/p/smhasher/">MurmurHash3</a> and <a href="http://code.google.com/p/cityhash/">Google&#8217;s CityHash</a>), although they tend to be more machine specific. These may also be appropriate for hashing a binary representation of your data - providing that all equal values have an equal representation, which is not always the case (e.g. for floating point values).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="ref"><a class="link" href="#ref">Reference</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>For the full specification, see section 6.3 of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</a> and issue 6.18 of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</a> (page 63).</p>
</div>
<div class="sect2">
<h3 id="ref_header_boostcontainer_hashhash_hpp"><a class="link" href="#ref_header_boostcontainer_hashhash_hpp">Header &lt;boost/container_hash/hash.hpp&gt;</a></h3>
<div class="paragraph">
<p>Defines <code>boost::hash</code>, and helper functions.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="p">;</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">signed</span> <span class="kt">char</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">char</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">wchar_t</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">char16_t</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">char32_t</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">short</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">short</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">double</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">wstring</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">u16string</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">u32string</span><span class="o">&gt;</span><span class="p">;</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">type_index</span><span class="o">&gt;</span><span class="p">;</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">T</span><span class="o">*&gt;</span><span class="p">;</span>

  <span class="c1">// Support functions (Boost extension).</span>
  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
  <span class="kt">void</span> <span class="n">hash_combine</span><span class="p">(</span><span class="kt">size_t</span> <span class="o">&amp;</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">It</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_range</span><span class="p">(</span><span class="n">It</span><span class="p">,</span> <span class="n">It</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">It</span><span class="p">&gt;</span>
  <span class="kt">void</span> <span class="n">hash_range</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">It</span><span class="p">,</span> <span class="n">It</span><span class="p">);</span>

  <span class="c1">// Overloadable hash implementation (Boost extension).</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">bool</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">char</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">signed</span> <span class="kt">char</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">wchar_t</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">char16_t</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">char32_t</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">short</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">int</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">long</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">long</span> <span class="kt">long</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">float</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">double</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="kt">long</span> <span class="kt">double</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">T</span><span class="o">*</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">N</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">T</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">val</span><span class="p">)[</span><span class="n">N</span><span class="p">]);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">N</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">val</span><span class="p">)[</span><span class="n">N</span><span class="p">]);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">Ch</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o">&lt;</span><span class="n">Ch</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">Ch</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">A</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">B</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">deque</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">multiset</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">multimap</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">complex</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">type_index</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span>

  <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span><span class="o">...</span> <span class="nc">T</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="n">T</span><span class="p">...</span><span class="o">&gt;</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_struct_template_hash"><a class="link" href="#ref_struct_template_hash">Struct template hash</a></h3>
<div class="sect3">
<h4 id="ref_hash"><a class="link" href="#ref_hash">hash</a></h4>
<div class="paragraph">
<p><code>boost::hash</code> — A <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</a> compliant hash function object.</p>
</div>
<div class="sect4">
<h5 id="ref_synopsis"><a class="link" href="#ref_synopsis">Synopsis</a></h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="c1">// #include &lt;boost/container_hash/hash.hpp&gt;</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">hash</span> <span class="o">:</span> <span class="k">public</span> <span class="n">std</span><span class="o">::</span><span class="n">unary_function</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="k">operator</span><span class="p">()(</span><span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_description"><a class="link" href="#ref_description">Description</a></h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="k">operator</span><span class="p">()(</span><span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Returns
</td>
<td class="hdlist2">
<p><code>hash_value(val)</code></p>
</td>
</tr>
<tr>
<td class="hdlist1">
Notes
</td>
<td class="hdlist2">
<p>The call to <code>hash_value</code> is unqualified, so that custom overloads can be found via argument dependent lookup.</p>
<div class="paragraph">
<p>This is not defined when the macro <code>BOOST_HASH_NO_EXTENSIONS</code> is defined. The specializations are still defined, so only the specializations required by TR1 are defined.</p>
</div>
<div class="paragraph">
<p>Forward declared in <code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code></p>
</div>
<div class="paragraph">
<p>This hash function is not intended for general use, and isn&#8217;t guaranteed to be equal during separate runs of a program - so please don&#8217;t use it for any persistent storage or communication.</p>
</div>
</td>
</tr>
<tr>
<td class="hdlist1">
Throws
</td>
<td class="hdlist2">
<p>Only throws if <code>hash_value(T)</code> throws.</p>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_specializations"><a class="link" href="#ref_specializations">Specializations</a></h3>
<div class="paragraph">
<p><code>boost::hash&lt;T&gt;</code></p>
</div>
<div class="sect3">
<h4 id="ref_synopsis_2"><a class="link" href="#ref_synopsis_2">Synopsis</a></h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="c1">// #include &lt;boost/container_hash/hash.hpp&gt;</span>

<span class="k">struct</span> <span class="nc">hash</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="k">operator</span><span class="p">()(</span><span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_description_2"><a class="link" href="#ref_description_2">Description</a></h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="k">operator</span><span class="p">()(</span><span class="n">T</span> <span class="k">const</span> <span class="n">val</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Returns
</td>
<td class="hdlist2">
<p>Unspecified in TR1, except that equal arguments yield the same result.</p>
<div class="paragraph">
<p><code>hash_value(val)</code> in Boost.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Throws
</td>
<td class="hdlist2">
<p>Doesn&#8217;t throw</p>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_support_functions_boost_extension"><a class="link" href="#ref_support_functions_boost_extension">Support functions (Boost extension).</a></h3>
<div class="sect3">
<h4 id="ref_hash_combine"><a class="link" href="#ref_hash_combine">hash_combine</a></h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">hash_combine</span><span class="p">(</span><span class="kt">size_t</span> <span class="o">&amp;</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Called repeatedly to incrementally create a hash value from several variables.</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Effects
</td>
<td class="hdlist2">
<p>Updates seed with a new hash value generated by combining it with the result of <code>hash_value(v)</code>. Will always produce the same result for the same combination of seed and <code>hash_value(v)</code> during the single run of a program.</p>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Notes
</td>
<td class="hdlist2">
<p><code>hash_value</code> is called without qualification, so that overloads can be found via ADL.<br></p>
<div class="paragraph">
<p>This is an extension to TR1<br></p>
</div>
<div class="paragraph">
<p>Forward declared in <code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code><br></p>
</div>
<div class="paragraph">
<p>This hash function is not intended for general use, and isn&#8217;t guaranteed to be equal during separate runs of a program - so please don&#8217;t use it for any persistent storage or communication.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Throws
</td>
<td class="hdlist2">
<p>Only throws if <code>hash_value(T)</code> throws. Strong exception safety, as long as <code>hash_value(T)</code> also has strong exception safety.</p>
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="ref_hash_range"><a class="link" href="#ref_hash_range">hash_range</a></h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_range</span><span class="p">(</span><span class="n">It</span><span class="p">,</span> <span class="n">It</span><span class="p">);</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">hash_range</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">It</span><span class="p">,</span> <span class="n">It</span><span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Calculate the combined hash value of the elements of an iterator range.</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Effects
</td>
<td class="hdlist2">
<p>For the two argument overload:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="k">for</span><span class="p">(;</span> <span class="n">first</span> <span class="o">!=</span> <span class="n">last</span><span class="p">;</span> <span class="o">++</span><span class="n">first</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="o">*</span><span class="n">first</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">seed</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>For the three arguments overload:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">for</span><span class="p">(;</span> <span class="n">first</span> <span class="o">!=</span> <span class="n">last</span><span class="p">;</span> <span class="o">++</span><span class="n">first</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="o">*</span><span class="n">first</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Notes
</td>
<td class="hdlist2">
<p><code>hash_range</code> is sensitive to the order of the elements so it wouldn&#8217;t be appropriate to use this with an unordered container.</p>
<div class="paragraph">
<p>This is an extension to TR1</p>
</div>
<div class="paragraph">
<p>Forward declared in <code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code></p>
</div>
<div class="paragraph">
<p>This hash function is not intended for general use, and isn&#8217;t guaranteed to be equal during separate runs of a program - so please don&#8217;t use it for any persistent storage or communication.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Throws
</td>
<td class="hdlist2">
<p>Only throws if <code>hash_value(std::iterator_traits&lt;It&gt;::value_type)</code> throws. <code>hash_range(std::size_t&amp;, It, It)</code> has basic exception safety as long as <code>hash_value(std::iterator_traits&lt;It&gt;::value_type)</code> has basic exception safety.</p>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_overloadable_hash_implementation_boost_extension"><a class="link" href="#ref_overloadable_hash_implementation_boost_extension">Overloadable hash implementation (Boost extension).</a></h3>
<div class="sect3">
<h4 id="ref_hash_value"><a class="link" href="#ref_hash_value">hash_value</a></h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">bool</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">char</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">signed</span> <span class="kt">char</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">wchar_t</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">char16_t</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">char32_t</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">short</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">short</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">int</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">long</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">float</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">double</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="kt">long</span> <span class="kt">double</span> <span class="n">val</span><span class="p">);</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">T</span><span class="o">*</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">N</span><span class="p">&gt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">T</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">val</span><span class="p">)[</span><span class="n">N</span><span class="p">]);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">N</span><span class="p">&gt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">val</span><span class="p">)[</span><span class="n">N</span><span class="p">]);</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">Ch</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o">&lt;</span><span class="n">Ch</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o">&lt;</span><span class="n">Ch</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">A</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">B</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">B</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">deque</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">multiset</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">K</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">A</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">multimap</span><span class="o">&lt;</span><span class="n">K</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">A</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">complex</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">type_index</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">val</span><span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span><span class="o">...</span> <span class="nc">T</span><span class="p">&gt;</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">hash_value</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="n">T</span><span class="p">...</span><span class="o">&gt;</span> <span class="n">val</span><span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Implementation of the hash function.</p>
</div>
<div class="paragraph">
<p>Generally shouldn&#8217;t be called directly by users, instead they should use <code>boost::hash</code>, <code>boost::hash_range</code> or <code>boost::hash_combine</code> which call <code>hash_value</code> without namespace qualification so that overloads for custom types are found via ADL.</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Notes
</td>
<td class="hdlist2">
<p>This is an extension to TR1</p>
<div class="paragraph">
<p>This hash function is not intended for general use, and isn&#8217;t guaranteed to be equal during separate runs of a program - so please don&#8217;t use it for any persistent storage or communication.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
Throws
</td>
<td class="hdlist2">
<p>Only throws if a user supplied version of <code>hash_value</code> throws for an element of a container, or one of the types stored in a pair.</p>
</td>
</tr>
</table>
</div>
<div class="dlist vertical">
<dl>
<dt>Returns</dt>
<dd>
<table class="tableblock frame-all grid-rows stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Types</th>
<th class="tableblock halign-left valign-top">Returns</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>bool</code>, <code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>, <code>char16_t</code>, <code>char32_t</code>, <code>short</code>, <code>unsigned short</code>, <code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">val</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>long long</code>, <code>unsigned long long</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">val when <code>abs(val) &lt;= std::numeric_limits&lt;std::size_t&gt;::max()</code>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float</code>, <code>double</code>, <code>long double</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unspecified value, except that equal arguments shall yield the same result.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>T*</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unspecified value, except that equal arguments shall yield the same result.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>T val[N]</code>, <code>const T val[N]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hash_range(val, val+N)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>std:basic_string&lt;Ch, std::char_traits&lt;Ch&gt;, A&gt;</code>, <code>std::vector&lt;T, A&gt;</code>, <code>std::list&lt;T, A&gt;</code>, <code>std::deque&lt;T, A&gt;</code>, <code>std::set&lt;K, C, A&gt;</code>, <code>std::multiset&lt;K, C, A&gt;</code>, <code>std::map&lt;K, T, C, A&gt;</code>, <code>std::multimap&lt;K, T, C, A&gt;</code>, <code>std::array&lt;T, N&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hash_range(val.begin(), val.end())</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>std::pair&lt;A, B&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">val</span><span class="p">.</span><span class="n">first</span><span class="p">);</span>
<span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">val</span><span class="p">.</span><span class="n">second</span><span class="p">);</span>
<span class="k">return</span> <span class="n">seed</span><span class="p">;</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>std::tuple&lt;T&#8230;&#8203;&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">val</span><span class="p">));</span>
<span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">get</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;</span><span class="p">(</span><span class="n">val</span><span class="p">));</span>
<span class="k">return</span> <span class="n">seed</span><span class="p">;</span></code></pre>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>std::complex&lt;T&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">When T is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>std::type_index</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>val.hash_code()</code></p></td>
</tr>
</tbody>
</table>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="links"><a class="link" href="#links">Links</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>A Proposal to Add Hash Tables to the Standard Library</strong> <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html" class="bare">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html</a> The hash table proposal explains much of the design. The hash function object is discussed in Section D.</p>
</div>
<div class="paragraph">
<p><strong>The C++ Standard Library Technical Report.</strong> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf" class="bare">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf</a> Contains the hash function specification in section 6.3.2.</p>
</div>
<div class="paragraph">
<p><strong>Library Extension Technical Report Issues List.</strong> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf" class="bare">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf</a> The library implements the extension described in Issue 6.18, pages 63-67.</p>
</div>
<div class="paragraph">
<p><strong>Methods for Identifying Versioned and Plagiarised Documents</strong> Timothy C. Hoad, Justin Zobel <a href="http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf" class="bare">http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf</a> Contains the hash function that <code>boost::hash_combine</code> is based on.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="thanks"><a class="link" href="#thanks">Acknowledgements</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library is based on the design by Peter Dimov. During the initial development Joaquín M López Muñoz made many useful suggestions and contributed fixes.</p>
</div>
<div class="paragraph">
<p>The formal review was managed by Thorsten Ottosen, and the library reviewed by: David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris, Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter, Rob Stewart and Pavel Vozenilek. Since then, further constructive criticism has been made by Daniel Krügler, Alexander Nasonov and 沈慧峰.</p>
</div>
<div class="paragraph">
<p>The implementation of the hash function for pointers is based on suggestions made by Alberto Barbati and Dave Harris. Dave Harris also suggested an important improvement to <code>boost::hash_combine</code> that was taken up.</p>
</div>
<div class="paragraph">
<p>Some useful improvements to the floating point hash algorithm were suggested by Daniel Krügler.</p>
</div>
<div class="paragraph">
<p>The original implementation came from Jeremy B. Maitin-Shepard&#8217;s hash table library, although this is a complete rewrite.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="copyright"><a class="link" href="#copyright">Copyright and License</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>Daniel James</strong></p>
</div>
<div class="paragraph">
<p>Copyright &#169; 2005-2008 Daniel James</p>
</div>
<div class="paragraph">
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" class="bare">http://www.boost.org/LICENSE_1_0.txt</a>)</p>
</div>
</div>
</div>
</div>
<div id="footnotes">
<hr>
<div class="footnote" id="_footnotedef_1">
<a href="#_footnoteref_1">1</a>. issue 6.18 of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</a> (page 63)
</div>
</div>
</body>
</html>